package com.rppowell.pixie.swing.importer;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextField;

public class SpriteSetImporterDialogPanel extends JPanel implements ActionListener, MouseListener, MouseMotionListener {

    private static final long serialVersionUID = 1L;

    private BufferedImage image;

    JPanel mainPanel;
    JPanel imagePanel;
    SpriteSetImporterImageCanvas imageCanvasPanel;
    JPanel toolPanel;
    JPanel optionsPanel;
    JPanel filenamePanel;
    JTextField filenameTextField;
    JButton filenameChangeButton;
    JPanel spriteOptionsPanel;
    JTextField spriteSetTextField;
    JSpinner widthSpinner;
    JSpinner heightSpinner;
    JSpinner xspacingSpinner;
    JSpinner yspacingSpinner;
    JSpinner xoffsetSpinner;
    JSpinner yoffsetSpinner;

    JPanel previewContainer;
    SpritePreviewPanel previewPanel;

    SpriteSetImporterDialogPanel() {
        setLayout(new BorderLayout());

        /*
         * imagePanel
         */
        imagePanel = new JPanel();
        imageCanvasPanel = new SpriteSetImporterImageCanvas();
        imageCanvasPanel.addMouseListener(this);

        JScrollPane jscrollpane = new JScrollPane(imageCanvasPanel);
        jscrollpane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        jscrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        imagePanel.setLayout(new BorderLayout());
        imagePanel.add(jscrollpane, BorderLayout.CENTER);

        add(imagePanel, BorderLayout.CENTER);

        /* 
         * toolPanel - optionsPanel
         */
        toolPanel = new JPanel();
        toolPanel.setLayout(new BorderLayout());

        optionsPanel = new JPanel();
        optionsPanel.setLayout(new BorderLayout());

        /*
         * toolPanel - optionsPanel - filenamePanel
         */
        filenamePanel = new JPanel();
        filenamePanel.setLayout(new BorderLayout());;
        filenamePanel.setBorder(
                BorderFactory.createTitledBorder("Image:")
        );
        filenameTextField = new JTextField(10);
        filenameTextField.setEnabled(false);;
        filenamePanel.add(filenameTextField, BorderLayout.CENTER);
        filenameChangeButton = new JButton("...");
        filenameChangeButton.addActionListener(this);
        filenamePanel.add(filenameChangeButton, BorderLayout.EAST);
        optionsPanel.add(filenamePanel, BorderLayout.NORTH);

        toolPanel.add(optionsPanel, BorderLayout.NORTH);

        /*
         * toolPanel - optionsPanel - spriteOptionsPanel
         */
        spriteOptionsPanel = new JPanel();
        spriteOptionsPanel.setBorder(
                BorderFactory.createTitledBorder("Sprite Set Options:")
        );

        spriteOptionsPanel.setLayout(new FlowLayout());
        GridLayout g = new GridLayout(7, 2);
        spriteOptionsPanel.setLayout(g);

        spriteOptionsPanel.add(new JLabel("Name:"));
        spriteSetTextField = new JTextField(7);
        spriteOptionsPanel.add(spriteSetTextField);

        spriteOptionsPanel.add(new JLabel("Width:"));
        widthSpinner = new JSpinner();
        spriteOptionsPanel.add(widthSpinner);

        spriteOptionsPanel.add(new JLabel("Height:"));
        heightSpinner = new JSpinner();
        spriteOptionsPanel.add(heightSpinner);

        spriteOptionsPanel.add(new JLabel("X-Spacing:"));
        xspacingSpinner = new JSpinner();
        spriteOptionsPanel.add(xspacingSpinner);

        spriteOptionsPanel.add(new JLabel("Y-Spacing:"));
        yspacingSpinner = new JSpinner();
        spriteOptionsPanel.add(yspacingSpinner);

        spriteOptionsPanel.add(new JLabel("X-offset:"));
        xoffsetSpinner = new JSpinner();
        spriteOptionsPanel.add(xoffsetSpinner);

        spriteOptionsPanel.add(new JLabel("Y-offset:"));
        yoffsetSpinner = new JSpinner();
        spriteOptionsPanel.add(yoffsetSpinner);

        optionsPanel.add(spriteOptionsPanel, BorderLayout.CENTER);

        /*
         * toolPanel - previewContainer
         */
        previewContainer = new JPanel();
        previewContainer.setBorder(BorderFactory.createTitledBorder("Sprite Preview:"));
        previewContainer.setLayout(new BorderLayout());
        previewPanel = new SpritePreviewPanel();
        previewContainer.add(previewPanel, BorderLayout.CENTER);

        toolPanel.add(previewContainer, BorderLayout.CENTER);
        add(toolPanel, BorderLayout.EAST);

        setDefaults();
        setPreferredSize(new Dimension(640, 480));
    }

    private void setDefaults() {
        widthSpinner.getModel().setValue(16);
        heightSpinner.getModel().setValue(16);
        xspacingSpinner.getModel().setValue(0);
        yspacingSpinner.getModel().setValue(0);
        xoffsetSpinner.getModel().setValue(0);
        yoffsetSpinner.getModel().setValue(0);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == filenameChangeButton) {
            doFileChooser();
        }
    }

    private void doFileChooser() {
        JFileChooser fc = new JFileChooser();
        fc.addChoosableFileFilter(new ImageFileSelectorFilter());
		// fc.setAcceptAllFileFilterUsed(false)
        // Add custom icons for file types
        fc.setAccessory(new ImageFileSelectorPreview(fc));

        int i = fc.showOpenDialog(this);
        if (i == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            setImage(file);
        }
    }

    private void setImage(File f) {
        try {
            image = ImageIO.read(f);
            filenameTextField.setText(f.getName());
            imageCanvasPanel.setImage(image);
        } catch (IOException e) {
            // TODO SpriteSheetImporterDialogPanel setImage(File f) IOException
            e.printStackTrace();
        }
    }

    private void updatePreviewPosition(int x, int y) {
        if (image != null) {
            int w = (Integer) widthSpinner.getModel().getValue();
            int h = (Integer) heightSpinner.getModel().getValue();
            int xs = (Integer) xspacingSpinner.getModel().getValue();
            int ys = (Integer) yspacingSpinner.getModel().getValue();
            int xo = (Integer) xoffsetSpinner.getModel().getValue();
            int yo = (Integer) yoffsetSpinner.getModel().getValue();

            int wt = w + xs;
            int ht = h + ys;

            int i = (x / wt) * wt;
            int j = (y / ht) * ht;
            if ((i < image.getWidth()) && (j < image.getHeight()) && (i + w <= image.getWidth()) && (j + h <= image.getHeight())) {
                previewPanel.setImage(image.getSubimage(i, j, w, h));;
            }
        }
    }

    public SpriteSetImporterProperties generateImporterProperties() {
        SpriteSetImporterProperties i = null;
        i = new SpriteSetImporterProperties(
                image,
                spriteSetTextField.getText(),
                (Integer) widthSpinner.getModel().getValue(),
                (Integer) heightSpinner.getModel().getValue(),
                (Integer) xspacingSpinner.getModel().getValue(),
                (Integer) yspacingSpinner.getModel().getValue(),
                (Integer) xoffsetSpinner.getModel().getValue(),
                (Integer) yoffsetSpinner.getModel().getValue()
        );
        return i;
    }

    @Override
    public void mouseDragged(MouseEvent e) {
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("mouseClicked(" + e.toString() + ")");
        updatePreviewPosition(e.getX(), e.getY());
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent arg0) {
    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
    }
}
